<script lang="ts" setup>
import { useUserStore } from '@/store/user';
import { BASE_URL } from '@/utils/constant';
import { io, type Socket } from 'socket.io-client';
import { ref } from 'vue';
import type { OrderDetail } from '@/types/consult';
import { orderDetailApi } from '@/apis/consult';
import type { MsgData, MsgItem } from '@/types/room';
import { MsgType } from '@/enums';

import RoomStatus from './components/room-status.vue';
import PatientInfo from './components/patient-info.vue';
import NotifyInfo from './components/notify-info.vue';
import MessageInfo from './components/message-info.vue';
import PrescriptionInfo from './components/prescription-info.vue';


// 消息列表
const messageList = ref<MsgItem[]>([])

const store = useUserStore()

/**
  1. socket建立长连接后, 如果断开了, 内部会如何处理?
  - 一般一些基于websocket的即时通讯库都有 心跳包机制, 客户端如果一定时间没有和服务端通信, 就会开启心跳包, 在一定的频率下发空消息包给服务器, 确保连接还是建立的
  - 一旦消息发送不成功, 会尝试自动连接, 多次连接无果, 则触发断开连接的事件监听, 此时我们可以在里面进行手动连接
 */

// 1. 处理支付失败情况
const props = defineProps<{
  payResult: string,
  orderId: string
}>()
if(props.payResult === 'false'){
  uni.switchTab({
    url: '/pages/my/index',
  })
}


// 2.  连接socket服务器
const socket: Socket = io(BASE_URL, {
  auth: { token: 'Bearer ' + store.token },
  query: { orderId: props.orderId },
  transports: ['websocket', 'polling'],
  timeout: 5000
})

socket.on('connect', () => {
  // 建立连接成功
  console.log('连接建立成功')
})

socket.on('error', () => {
  // 错误异常消息
  console.log('出现错误')
})

socket.on('disconnect', () => {
  // 已经断开连接
  console.log('断开连接')
})


// 3. 获取订单详情
const orderDetail = ref<OrderDetail>({} as OrderDetail)
const getOrderDetail = async ()=>{
  if(!props.orderId) return uni.showToast({title: '没有订单id'})
  const res = await orderDetailApi(props.orderId)
  orderDetail.value = res
}
getOrderDetail()

// 3.1 处理订单状态变化
socket.on('statusChange', (e)=>{
  getOrderDetail()
})

// 4. 获取消息列表
socket.on('chatMsgList', (res: MsgData)=>{
  if(res.code !== 10000) return 
  res.data?.forEach(({ items }) => {
    messageList.value.push(...items!)
  })
})

// 5. 接收实时消息(自己发的 / 医生发的 --> 服务器推的)
socket.on('receiveChatMsg', (message: MsgItem)=>{
  // 标记消息已读
  socket.emit('updateMsgStatus', message.id) 
  // 接收到的消息追加到消息列表中
  messageList.value.push(message)
})

</script>

<template>
  <view class="room-page">
    <!-- 聊天室状态  -->
    <room-status v-if="orderDetail.id" :status="orderDetail.status" :statusValue="orderDetail.statusValue"
      :countdown="orderDetail.countdown" />
    <scroll-view refresher-enabled refresher-background="#f2f2f2" scroll-y style="flex: 1; overflow: hidden">
      <view class="message-container">
        <!-- 此处将来填充更多代码... -->
        <template v-for="msg in messageList" :key="msg.id">
          <!-- 患者消息 -->
          <patient-info v-if="msg.msgType === MsgType.CardPat" :consult-record="msg.msg?.consultRecord!" />
          <!-- 通知消息 -->
          <notify-info v-if="msg.msgType! >= 31" :msg-item="msg" />
          <!-- 图片/文字消息 -->
          <message-info v-if="msg.msgType === MsgType.MsgText || msg.msgType === MsgType.MsgImage" :info="msg" />
          <!-- 处方消息 -->
          <prescription-info v-if="msg.msgType === MsgType.CardPre" :info="msg.msg?.prescription!" />
        </template>
      </view>
    </scroll-view>

    <!-- 发送消息 -->
    <view class="message-bar">
      <template v-if="true">
        <uni-easyinput disabled :clearable="false" :input-border="false"
          placeholder-style="font-size: 32rpx; color: #c3c3c5;" placeholder="问医生" />
        <view class="image-button">
          <uni-icons size="40" color="#979797" type="image"></uni-icons>
        </view>
      </template>
      <button v-else class="uni-button">咨询其它医生</button>
    </view>
  </view>
</template>

<style lang="scss">
@import './index.scss';
</style>